/*
 * $Id: socket.h,v 1.30 2006-04-03 11:32:48 bacon Exp $
 */
 
#ifndef _XP_NET_SOCKET_H_
#define _XP_NET_SOCKET_H_

#include <xp/types.h>
#include <xp/macros.h>

#ifdef _WIN32
	#ifdef XP_WINSOCK_IN_ORDER
	#include <windows.h>
	#include <winsock2.h>
	#include <ws2tcpip.h> /* sockaddr_in6 */
	#else
	#include <winsock2.h>
	#include <ws2tcpip.h> /* sockaddr_in6 */
	#include <windows.h>
	#endif
#else
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
#endif

#include <xp/bas/time.h>

typedef struct sockaddr xp_sckadr_t;
typedef struct sockaddr_in xp_sckadrin4_t;
typedef struct sockaddr_in6 xp_sckadrin6_t;

#if defined(_WIN32)
	typedef SOCKET xp_sckhnd_t;
	typedef int xp_scklen_t;
	#define XP_SCKHND_INVALID INVALID_SOCKET
#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__)
	typedef int xp_sckhnd_t;
	typedef socklen_t xp_scklen_t;
	#define XP_SCKHND_INVALID (-1)
#else 
	typedef int xp_sckhnd_t;
	typedef int xp_scklen_t;
	#define XP_SCKHND_INVALID (-1)
#endif

#ifdef __cplusplus
extern "C" {
#endif

int xp_sckstartup (void);
int xp_sckcleanup (void);

xp_sckhnd_t xp_sckopen (int domain, int type, int proto);
int xp_sckclose (xp_sckhnd_t hnd);
int xp_sckshtdwn (xp_sckhnd_t hnd, int how);

int xp_sckconn (
	xp_sckhnd_t hnd, const xp_sckadr_t* addr, 
	xp_scklen_t len, xp_time_t tmout);
int xp_sckconnx (
	xp_sckhnd_t hnd, const xp_sckadr_t* addr, xp_scklen_t len, 
	xp_time_t tmout, xp_bool_t (*cancel) (void*), void* arg);

int xp_sckbind (
	xp_sckhnd_t hnd, 
	xp_sckadr_t* addr, xp_scklen_t len);
int xp_scklstn (
	xp_sckhnd_t hnd, int backlog);
xp_sckhnd_t xp_sckacpt (
	xp_sckhnd_t hnd, xp_sckadr_t* addr,
	xp_scklen_t* len, xp_time_t tmout);

xp_ssize_t xp_sckrecv (
	xp_sckhnd_t hnd, void* buf, 
	xp_size_t len, int flags, xp_time_t tmout);
xp_ssize_t xp_sckrecvall (
	xp_sckhnd_t hnd, void* buf,
	xp_size_t len, int flags, xp_time_t tmout);

xp_ssize_t xp_scksend (
	xp_sckhnd_t hnd, const void* msg,
	 xp_size_t len, int flags, xp_time_t tmout);
xp_ssize_t xp_scksendall (
	xp_sckhnd_t hnd, const void* msg, 
	xp_size_t len, int flags, xp_time_t tmout);

xp_ssize_t xp_sckrecvfrom (
	xp_sckhnd_t hnd, void* buf, xp_size_t len, int flags,
	xp_sckadr_t* from, xp_scklen_t* fromlen, xp_time_t tmout);
xp_ssize_t xp_scksendto (
	xp_sckhnd_t hnd, const void* msg, xp_size_t len, int flags, 
	const xp_sckadr_t* to, xp_scklen_t tolen, xp_time_t tmout);

int xp_sckgetopt (xp_sckhnd_t hnd, int level,
	int optname, void* optval, xp_scklen_t* optlen);
int xp_scksetopt (xp_sckhnd_t hnd, int level,
	int optname, const void* optval, xp_scklen_t optlen);

int xp_sckgetself (xp_sckhnd_t hnd, xp_sckadr_t* name, xp_scklen_t* len);
int xp_sckgetpeer (xp_sckhnd_t hnd, xp_sckadr_t* name, xp_scklen_t* len);

#ifdef __cplusplus
}
#endif

#endif
